using Gateway.Common.Enums;
using Gateway.IQuery;
using Gateway.IQuery.DataDic;
using Gateway.IQuery.DataDic.Request;
using Gateway.IQuery.DataDic.Result;
using Gateway.IRepositories;
using SqlSugar;

namespace Gateway.Query;

/// <summary>
/// 数据字典 查询服务
/// </summary>
public class DataDicQuery : IDataDicQuery
{
    private readonly IQueryRepository _queryRepository;

    /// <summary>
    /// 
    /// </summary>
    /// <param name="queryRepository"></param>
    public DataDicQuery(IQueryRepository queryRepository)
    {
        _queryRepository = queryRepository;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <returns></returns>
    public async Task<List<DataDicDetailResult>> GetAll()
    {
        return await _queryRepository.GetListAsync<DataDicDetailResult>(_ => true);
    }

    /// <summary>
    /// <see cref="IDataDicQuery.GetListByCode(string)"/>
    /// </summary>
    public async Task<List<DataDicDetailResult>> GetListByCode(string code)
    {
        var data = await _queryRepository.FindAsync<DataDicDetailResult>(x => x.Code.Equals(code));
        if (data == null)
        {
            return new List<DataDicDetailResult>();
        }

        var list = await _queryRepository.GetListAsync<DataDicDetailResult>(x => x.ParentId.Equals(data.ParentId)
            && x.Disabled ==
            BooleanStatusEnum.No.Value
        );
        return list;
    }

    /// <summary>
    /// 获取 分页列表
    /// </summary>
    /// <param name="request"></param>
    /// <returns></returns>
    public async Task<PageResult<DataDicDetailResult>> GetList(DataDicPageRequest request)
    {
        RefAsync<int> count = 0;
        var data = await _queryRepository.Db.Queryable<DataDicDetailResult>()
            .Where(x => (string.IsNullOrEmpty(request.Name) || x.Name.Contains(request.Name))
                        && (string.IsNullOrEmpty(request.ParentId) || x.ParentId.Equals(request.ParentId))
                        && (string.IsNullOrEmpty(request.DataDicType) || x.DicType.Equals(request.DataDicType))
            ).ToPageListAsync(request.Page, request.PageSize, count);

        return PageResult<DataDicDetailResult>.Create(data.ToList(), count);
    }

    /// <summary>
    /// 获取所有的 类别的 数据字典
    /// </summary>
    /// <returns></returns>
    public async Task<List<DataDicCategoryTreeResult>> GetCategoryList()
    {
        var list = await _queryRepository.GetListAsync<DataDicDetailResult>(x =>
            x.DicType == (DataDicTypeEnum.Category.Value));
        var rootList = list.Where(p => string.IsNullOrWhiteSpace(p.ParentId)).OrderBy(p => p.Sort).ToList();
        List<DataDicCategoryTreeResult> result = new List<DataDicCategoryTreeResult>();
        foreach (var item in rootList)
        {
            var data = GetAggregateRoot(item, list);
            result.AddRange(data);
        }

        return result;
    }


    /// <summary>
    /// 递归组织结构
    /// </summary>
    /// <param name="root"></param>
    /// <param name="list"></param>
    /// <returns></returns>
    private List<DataDicCategoryTreeResult> GetAggregateRoot(DataDicDetailResult root, List<DataDicDetailResult> list)
    {
        List<DataDicCategoryTreeResult> result = new List<DataDicCategoryTreeResult>();
        var rootModel = new DataDicCategoryTreeResult()
        {
            DataDicId = root.DataDicId,
            Name = root.Name,
            Code = root.Code,
            Sort = root.Sort,
            ParentId = root.ParentId
        };
        rootModel.Children = new List<DataDicCategoryTreeResult>();
        string id = root.DataDicId;
        if (!string.IsNullOrWhiteSpace(id))
        {
            var child = list.Where(p => (p.ParentId ?? "").Equals(id)).OrderBy(p => p.Sort).ToList();
            if (child.Count > 0)
            {
                foreach (var item in child)
                {
                    var tmpList = GetAggregateRoot(item, list);
                    rootModel.Children.AddRange(tmpList);
                }
            }
        }

        result.Add(rootModel);
        return result.OrderBy(p => p.Sort).ToList();
    }
}